package com.asen.libcommon.util.permission

import android.Manifest
import android.annotation.SuppressLint
import android.app.AppOpsManager
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.location.LocationManager
import android.os.Binder
import android.os.Build
import android.provider.Settings
import androidx.core.app.AppOpsManagerCompat
import androidx.core.app.AppOpsManagerCompat.noteOp
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.asen.libcommon.R
import com.asen.libcommon.util.xpopup.extQuickShow
import com.asen.libcommon.widget.CommonHintWindow
import com.asen.libcommon.widget.ToastUtils.showToast
import com.tbruyelle.rxpermissions2.RxPermissions
import java.lang.NullPointerException


/**
 * @author 小强
 *
 * @time 2020/5/8  09:15
 *
 * @desc 权限申请
 *
 */
object PermissionHelper {


    /**
     * 申请相机权限
     * @param activity Any? 上下文
     * @param onSuccessCall  成功回调
     * @param onCancelCall 失败回调
     */
    fun requestCameraPermission(
        activity: Any?,
        onSuccessCall: (() -> Unit)? = null,
        onCancelCall: (() -> Unit)? = null
    ) {

        var mRxPermissions: RxPermissions? = null
        var mContext: Context? = null

        if (activity is FragmentActivity) {
            mContext = activity
            mRxPermissions = RxPermissions(activity)
        } else if (activity is Fragment) {
            mContext = activity.context
            mRxPermissions = RxPermissions(activity)
        }

        activity?.let {
            mRxPermissions?.requestEachCombined(
                Manifest.permission.CAMERA,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE
            )
                ?.subscribe {
                    when {

                        //通过
                        it.granted -> {
                            onSuccessCall?.invoke()
                        }
                        //未通过
                        it.shouldShowRequestPermissionRationale -> {

                            val dialog = PermissionDialog.newBuilder()
                                .setTitle(
                                    mContext?.resources?.getString(R.string.common_reminder) ?: ""
                                )
                                .setContent(
                                    mContext?.resources?.getString(R.string.common_camera_permission)
                                        ?: ""
                                )
                                .setRightText(
                                    mContext?.resources?.getString(R.string.common_allow) ?: ""
                                )
                                .build()
                                ?.setOnConfirmClickListener {
                                    requestCameraPermission(activity, onSuccessCall, onCancelCall)
                                }?.setOnCancelClickListener {
                                    onCancelCall?.invoke()
                                }

                            if (activity is FragmentActivity) {
                                dialog?.show(activity.supportFragmentManager, "permission_dialog")
                            } else if (activity is Fragment) {
                                dialog?.show(activity.childFragmentManager, "permission_dialog")
                            }

                        }
                        else -> {
                            //禁止后不在提示
                            val dialog = PermissionDialog.newBuilder()
                                .setTitle(
                                    mContext?.resources?.getString(R.string.common_reminder) ?: ""
                                )
                                .setContent(
                                    mContext?.resources?.getString(R.string.common_not_camera_permission)
                                        ?: ""
                                )
                                .setRightText(
                                    mContext?.resources?.getString(R.string.common_go_open_it) ?: ""
                                )
                                .build()
                                ?.setOnConfirmClickListener {
                                    PermissionPageUtil.gotoPermission(mContext)
                                }?.setOnCancelClickListener {
                                    onCancelCall?.invoke()
                                }

                            if (activity is FragmentActivity) {
                                dialog?.show(activity.supportFragmentManager, "permission_dialog")
                            } else if (activity is Fragment) {
                                dialog?.show(activity.childFragmentManager, "permission_dialog")
                            }
                        }
                    }
                }
        }
    }


    /**
     * 读写权限
     * @param activity Any? 上下文
     * @param onSuccessCall  成功回调
     * @param onCancelCall 失败回调
     */
    fun requestReadExternalStoragePermission(
        activity: Any?,
        onSuccessCall: (() -> Unit)? = null,
        onCancelCall: (() -> Unit)? = null
    ) {

        var mRxPermissions: RxPermissions? = null
        var mContext: Context? = null

        if (activity is FragmentActivity) {
            mContext = activity
            mRxPermissions = RxPermissions(activity)
        } else if (activity is Fragment) {
            mContext = activity.context
            mRxPermissions = RxPermissions(activity)
        }

        activity?.let {
            mRxPermissions?.requestEachCombined(
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE
            )
                ?.subscribe {
                    when {
                        //通过
                        it.granted -> {
                            onSuccessCall?.invoke()
                        }
                        //未通过
                        it.shouldShowRequestPermissionRationale -> {

                            val dialog = PermissionDialog.newBuilder()
                                .setTitle(
                                    mContext?.resources?.getString(R.string.common_reminder) ?: ""
                                )
                                .setContent(
                                    mContext?.resources?.getString(R.string.common_read_write_permission)
                                        ?: ""
                                )
                                .setRightText(
                                    mContext?.resources?.getString(R.string.common_allow) ?: ""
                                )
                                .build()
                                ?.setOnConfirmClickListener {
                                    requestReadExternalStoragePermission(
                                        activity,
                                        onSuccessCall,
                                        onCancelCall
                                    )
                                }?.setOnCancelClickListener {
                                    onCancelCall?.invoke()
                                }

                            if (activity is FragmentActivity) {
                                dialog?.show(activity.supportFragmentManager, "permission_dialog")
                            } else if (activity is Fragment) {
                                dialog?.show(activity.childFragmentManager, "permission_dialog")
                            }

                        }
                        else -> {

                            //禁止后不在提示
                            val dialog = PermissionDialog.newBuilder()
                                .setTitle(
                                    mContext?.resources?.getString(R.string.common_reminder) ?: ""
                                )
                                .setContent(
                                    mContext?.resources?.getString(R.string.common_not_read_write_permission)
                                        ?: ""
                                )
                                .setRightText(
                                    mContext?.resources?.getString(R.string.common_go_open_it) ?: ""
                                )
                                .build()
                                ?.setOnConfirmClickListener {
                                    PermissionPageUtil.gotoPermission(mContext)
                                }?.setOnCancelClickListener {
                                    onCancelCall?.invoke()
                                }

                            if (activity is FragmentActivity) {
                                dialog?.show(activity.supportFragmentManager, "permission_dialog")
                            } else if (activity is Fragment) {
                                dialog?.show(activity.childFragmentManager, "permission_dialog")
                            }

                        }
                    }
                }
        }
    }


    /**
     * 定位权限
     * @param activity Any? 上下文
     * @param onSuccessCall  成功回调
     * @param onCancelCall 失败回调
     */
    fun requestLocationPermission(
        activity: Any?,
        onSuccessCall: (() -> Unit)? = null,
        onCancelCall: (() -> Unit)? = null
    ) {

        var mRxPermissions: RxPermissions? = null
        var mContext: Context? = null

        if (activity is FragmentActivity) {
            mContext = activity
            mRxPermissions = RxPermissions(activity)
        } else if (activity is Fragment) {
            mContext = activity.context
            mRxPermissions = RxPermissions(activity)
        }

        if (mContext == null) {
            throw NullPointerException("mContext 值为空，传入的Activity为${activity}")
        }

        /** 判断是否开启位置服务 */
        if (!isLocationServiceEnable(mContext)) {
            val dialog = PermissionDialog.newBuilder()
                .setTitle("温馨提示")
                .setContent("打开启位置服务，获取精准定位")
                .setRightText("去开启")
                .build()
                ?.setOnConfirmClickListener {
                    val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
                    mContext.startActivity(intent)
                }?.setOnCancelClickListener {
                    showToast("请打开启位置服务，获取精准定位");
                }
            if (activity is FragmentActivity) {
                dialog?.show(activity.supportFragmentManager, "permission_dialog")
            } else if (activity is Fragment) {
                dialog?.show(activity.childFragmentManager, "permission_dialog")
            }
            return
        }
        activity?.let {
            mRxPermissions?.requestEachCombined(
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION
            )
                ?.subscribe {
                    when {

                        //通过
                        it.granted -> {
                            onSuccessCall?.invoke()
                        }
                        //未通过
                        it.shouldShowRequestPermissionRationale -> {

                            val dialog = PermissionDialog.newBuilder()
                                .setTitle(
                                    mContext?.resources?.getString(R.string.common_reminder) ?: ""
                                )
                                .setContent(
                                    mContext?.resources?.getString(R.string.common_location_permission)
                                        ?: ""
                                )
                                .setRightText(
                                    mContext?.resources?.getString(R.string.common_allow) ?: ""
                                )
                                .build()
                                ?.setOnConfirmClickListener {
                                    requestLocationPermission(activity, onSuccessCall, onCancelCall)
                                }?.setOnCancelClickListener {
                                    onCancelCall?.invoke()
                                }

                            if (activity is FragmentActivity) {
                                dialog?.show(activity.supportFragmentManager, "permission_dialog")
                            } else if (activity is Fragment) {
                                dialog?.show(activity.childFragmentManager, "permission_dialog")
                            }

                        }

                        else -> {

                            //禁止后不在提示
                            val dialog = PermissionDialog.newBuilder()
                                .setTitle(
                                    mContext?.resources?.getString(R.string.common_reminder) ?: ""
                                )
                                .setContent(
                                    mContext?.resources?.getString(R.string.common_not_location_permission)
                                        ?: ""
                                )
                                .setRightText(
                                    mContext?.resources?.getString(R.string.common_go_open_it) ?: ""
                                )
                                .build()
                                ?.setOnConfirmClickListener {
                                    PermissionPageUtil.gotoPermission(mContext)
                                }?.setOnCancelClickListener {
                                    onCancelCall?.invoke()
                                }

                            if (activity is FragmentActivity) {
                                dialog?.show(activity.supportFragmentManager, "permission_dialog")
                            } else if (activity is Fragment) {
                                dialog?.show(activity.childFragmentManager, "permission_dialog")
                            }

                        }
                    }
                }
        }
    }


    /**
     * 录音视频权限
     * @param activity Any? 上下文
     * @param onSuccessCall  成功回调
     * @param onCancelCall 失败回调
     */
    fun requestAudioPermission(
        activity: Any?,
        onSuccessCall: (() -> Unit)? = null,
        onCancelCall: (() -> Unit)? = null
    ) {


        var mRxPermissions: RxPermissions? = null
        var mContext: Context? = null

        if (activity is FragmentActivity) {
            mContext = activity
            mRxPermissions = RxPermissions(activity)
        } else if (activity is Fragment) {
            mContext = activity.context
            mRxPermissions = RxPermissions(activity)
        }

        activity?.let {
            mRxPermissions?.requestEachCombined(Manifest.permission.RECORD_AUDIO)
                ?.subscribe {
                    when {
                        //通过
                        it.granted -> {
                            onSuccessCall?.invoke()
                        }
                        //未通过
                        it.shouldShowRequestPermissionRationale -> {

                            val dialog = PermissionDialog.newBuilder()
                                .setTitle(
                                    mContext?.resources?.getString(R.string.common_reminder) ?: ""
                                )
                                .setContent(
                                    mContext?.resources?.getString(R.string.common_audio_permission)
                                        ?: ""
                                )
                                .setRightText(
                                    mContext?.resources?.getString(R.string.common_allow) ?: ""
                                )
                                .build()
                                ?.setOnConfirmClickListener {
                                    requestAudioPermission(activity, onSuccessCall, onCancelCall)
                                }?.setOnCancelClickListener {
                                    onCancelCall?.invoke()
                                }

                            if (activity is FragmentActivity) {
                                dialog?.show(activity.supportFragmentManager, "permission_dialog")
                            } else if (activity is Fragment) {
                                dialog?.show(activity.childFragmentManager, "permission_dialog")
                            }

                        }
                        else -> {

                            //禁止后不在提示
                            val dialog = PermissionDialog.newBuilder()
                                .setTitle(
                                    mContext?.resources?.getString(R.string.common_reminder) ?: ""
                                )
                                .setContent(
                                    mContext?.resources?.getString(R.string.common_not_audio_permission)
                                        ?: ""
                                )
                                .setRightText(
                                    mContext?.resources?.getString(R.string.common_go_open_it) ?: ""
                                )
                                .build()
                                ?.setOnConfirmClickListener {
                                    PermissionPageUtil.gotoPermission(mContext)
                                }?.setOnCancelClickListener {
                                    onCancelCall?.invoke()
                                }

                            if (activity is FragmentActivity) {
                                dialog?.show(activity.supportFragmentManager, "permission_dialog")
                            } else if (activity is Fragment) {
                                dialog?.show(activity.childFragmentManager, "permission_dialog")
                            }


                        }
                    }
                }
        }
    }


    /**
     * IM权限
     * @param activity Any? 上下文
     * @param onSuccessCall  成功回调
     * @param onCancelCall 失败回调
     */
    fun requestIMPermission(
        activity: Any?,
        onSuccessCall: (() -> Unit)? = null,
        onCancelCall: (() -> Unit)? = null
    ) {

        var mRxPermissions: RxPermissions? = null

        if (activity is FragmentActivity) {
            mRxPermissions = RxPermissions(activity)
        } else if (activity is Fragment) {
            mRxPermissions = RxPermissions(activity)
        }

        activity?.let {
            mRxPermissions?.requestEachCombined(
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.CAMERA,
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.RECORD_AUDIO
            )?.subscribe {
                when {
                    //通过
                    it.granted -> {
                        onSuccessCall?.invoke()
                    }
                    else -> {
                        onCancelCall?.invoke()
                    }

                }
            }
        }
    }


    /**
     * 通讯权限
     * @param activity Any? 上下文
     * @param onSuccessCall  成功回调
     * @param onCancelCall 失败回调
     */
    fun requestContactsPermission(
        activity: Any?,
        onSuccessCall: (() -> Unit)? = null,
        onCancelCall: (() -> Unit)? = null
    ) {


        var mRxPermissions: RxPermissions? = null
        var mContext: Context? = null

        if (activity is FragmentActivity) {
            mContext = activity
            mRxPermissions = RxPermissions(activity)
        } else if (activity is Fragment) {
            mContext = activity.context
            mRxPermissions = RxPermissions(activity)
        }

        activity?.let {
            mRxPermissions?.requestEachCombined(
                // 2021/08/17 todo：删除通讯录申请使用，为应用宝上线
                //Manifest.permission.WRITE_CONTACTS,
                //Manifest.permission.READ_CONTACTS
            )
                ?.subscribe {
                    when {
                        //通过
                        it.granted -> {
                            onSuccessCall?.invoke()
                        }
                        //未通过
                        it.shouldShowRequestPermissionRationale -> {

                            val dialog = PermissionDialog.newBuilder()
                                .setTitle(
                                    mContext?.resources?.getString(R.string.common_reminder) ?: ""
                                )
                                .setContent(
                                    mContext?.resources?.getString(R.string.common_communication_permission)
                                        ?: ""
                                )
                                .setRightText(
                                    mContext?.resources?.getString(R.string.common_allow) ?: ""
                                )
                                .build()
                                ?.setOnConfirmClickListener {
                                    requestAudioPermission(activity, onSuccessCall, onCancelCall)
                                }?.setOnCancelClickListener {
                                    onCancelCall?.invoke()
                                }
                            if (activity is FragmentActivity) {
                                dialog?.show(activity.supportFragmentManager, "permission_dialog")
                            } else if (activity is Fragment) {
                                dialog?.show(activity.childFragmentManager, "permission_dialog")
                            }

                        }
                        else -> {

                            //禁止后不在提示
                            val dialog = PermissionDialog.newBuilder()
                                .setTitle(
                                    mContext?.resources?.getString(R.string.common_reminder) ?: ""
                                )
                                .setContent(
                                    mContext?.resources?.getString(R.string.common_not_communication_permission)
                                        ?: ""
                                )
                                .setRightText(
                                    mContext?.resources?.getString(R.string.common_go_open_it) ?: ""
                                )
                                .build()
                                ?.setOnConfirmClickListener {
                                    PermissionPageUtil.gotoPermission(mContext)
                                }?.setOnCancelClickListener {
                                    onCancelCall?.invoke()
                                }

                            if (activity is FragmentActivity) {
                                dialog?.show(activity.supportFragmentManager, "permission_dialog")
                            } else if (activity is Fragment) {
                                dialog?.show(activity.childFragmentManager, "permission_dialog")
                            }


                        }
                    }
                }
        }
    }


    /**
     * 检查系统定位服务权限
     */
    fun checkLocServicePermission(activity: FragmentActivity, onCancelCall: (() -> Unit)? = null) {
        if (!isLocServiceEnable(activity)) { // 检测是否开启定位服务
            PermissionDialog.newBuilder()
                .setTitle("温馨提示")
                .setContent("开启定位服务，获取精准定位")
                .setRightText("去开启")
                .build()
                ?.setOnConfirmClickListener {
                    PermissionPageUtil.gotoLocServicePage(activity)
                }
                ?.show(activity.supportFragmentManager, "location_dialog")
        } else { // 检测用户是否将当前应用的定位权限拒绝
            if (onCancelCall != null) {
                onCancelCall.invoke()
            } else {
                //其中2代表AppOpsManager.OP_GPS，如果要判断悬浮框权限，第二个参数需换成24即AppOpsManager。OP_SYSTEM_ALERT_WINDOW及，第三个参数需要换成AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW
                val checkResult = checkOp(activity, 2, AppOpsManager.OPSTR_FINE_LOCATION)
                val checkResult2 = checkOp(activity, 1, AppOpsManager.OPSTR_FINE_LOCATION)
                if (AppOpsManagerCompat.MODE_IGNORED == checkResult || AppOpsManagerCompat.MODE_IGNORED == checkResult2) {
                    // DlgUtils.showLocIgnoredDialog(this)
                }
            }
        }
    }

    /**
     * 手机是否开启位置服务，如果没有开启那么所有app将不能使用定位功能
     */
    private fun isLocServiceEnable(context: Context): Boolean {
        val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
        val gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
        val network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
        return gps || network
    }

    /**
     * 检查权限列表
     * 其中第二个参数2代表AppOpsManager.OP_GPS，
     * 如果要判断悬浮框权限，第二个参数需换成24即AppOpsManager.OP_SYSTEM_ALERT_WINDOW及，第三个参数需要换成AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW
     *
     * @param context
     * @param op 这个值被hide了，去AppOpsManager类源码找，如位置权限  AppOpsManager.OP_GPS==2
     * @param opString 如判断定位权限 AppOpsManager.OPSTR_FINE_LOCATION
     * @return  @see 如果返回值 AppOpsManagerCompat.MODE_IGNORED 表示被禁用了
     */
    fun checkOp(context: Context, op: Int, opString: String): Int {
        val version = Build.VERSION.SDK_INT
        if (version >= 19) {
            val obj = context.getSystemService(Context.APP_OPS_SERVICE)
            // Object object = context.getSystemService("appops");
            val c = obj.javaClass
            try {
                val cArg = arrayOfNulls<Class<*>>(3)
                cArg[0] = Int::class.javaPrimitiveType
                cArg[1] = Int::class.javaPrimitiveType
                cArg[2] = String::class.java
                val lMethod = c.getDeclaredMethod("checkOp", *cArg)
                return lMethod.invoke(obj, op, Binder.getCallingUid(), context.packageName) as Int
            } catch (e: Exception) {
                e.printStackTrace()
                if (Build.VERSION.SDK_INT >= 23) {
                    return noteOp(
                        context,
                        opString,
                        context.applicationInfo.uid,
                        context.packageName
                    )
                }
            }
        }
        return -1
    }

    /**
     * 判断手机是否开启位置服务
     * 如果没有开启那么所有app将不能使用定位功能
     */
    fun isLocationServiceEnable(context: Context): Boolean {
        val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
        val gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        val network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        if (gps || network) {
            return true;
        }
        return false;
    }

    /**
     * 申请录制权限：存储权限、摄像头权限、录音权限
     * @param activity Any 上下文
     * @param onSuccessCall  成功回调
     * @param onCancelCall 失败回调
     */
    @SuppressLint("CheckResult")
    fun requestRecordPermission(
        activity: Any,
        onSuccessCall: (() -> Unit)? = null,
        onCancelCall: (() -> Unit)? = null,
        onGotoPermission: (() -> Unit)? = null
    ) {
        var mRxPermissions: RxPermissions? = null
        var mContext: Context? = null
        if (activity is FragmentActivity) {
            mContext = activity
            mRxPermissions = RxPermissions(activity)
        } else if (activity is Fragment) {
            mContext = activity.requireContext()
            mRxPermissions = RxPermissions(activity)
        }
        if (mContext == null) {
            return
        }
        if (mRxPermissions == null) {
            return
        }
        mRxPermissions.requestEachCombined(
            Manifest.permission.CAMERA,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.RECORD_AUDIO
        ).subscribe {
            when {
                //通过
                it.granted -> onSuccessCall?.invoke()
                //未通过
                it.shouldShowRequestPermissionRationale -> {
                    CommonHintWindow(mContext)
                        .title(mContext.extString(R.string.common_reminder))
                        .content(mContext.extString(R.string.common_common_permission))
                        .cancel { onCancelCall?.invoke() }
                        .ensure(mContext.extString(R.string.common_allow)) {
                            requestRecordPermission(activity, onSuccessCall, onCancelCall)
                        }.extQuickShow()
                }
                else -> {
                    //禁止后不在提示
                    CommonHintWindow(mContext)
                        .title(mContext.extString(R.string.common_reminder))
                        .content(mContext.extString(R.string.common_not_common_permission))
                        .cancel { onCancelCall?.invoke() }
                        .ensure(mContext.extString(R.string.common_go_open_it)) {
                            PermissionPageUtil.gotoPermission(mContext)
                            onGotoPermission?.invoke()
                        }.extQuickShow()
                }
            }
        }
    }


    private fun Context.extString(resId: Int): String {
        return resources.getString(resId)
    }

    /**
     * 判断是否缺少权限
     */
    private fun checkPermission(mContexts: Context, permission: String): Boolean {
        return ContextCompat.checkSelfPermission(mContexts, permission) ==
                PackageManager.PERMISSION_DENIED
    }

    /**
     * 判断权限集合
     * permissions 权限数组
     * return false-表示没有改权限  true-表示权限已开启
     */
    fun checkPermissions(mContexts: Context, vararg mPermissions: String): Boolean {
        for (permission in mPermissions) {
            if (checkPermission(mContexts, permission)) {
                //没有开启权限
                return false
            }
        }
        //权限已开启
        return true
    }
}